package com.niiwoo.civet.trade.service.local.third;

import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.trade.dao.entity.Project;
import com.niiwoo.civet.trade.dao.entity.ProjectBorrowerPlan;
import com.niiwoo.civet.trade.dao.entity.ProjectBorrowerSummary;
import com.niiwoo.civet.trade.dao.mapper.ProjectBorrowerPlanMapperExt;
import com.niiwoo.civet.trade.dao.mapper.ProjectBorrowerSummaryMapperExt;
import com.niiwoo.civet.trade.dao.mapper.ProjectInvestorPlanMapperExt;
import com.niiwoo.civet.trade.dao.mapper.ProjectMapperExt;
import com.niiwoo.civet.trade.dto.ProjectBorrowerAmountSumDTO;
import com.niiwoo.civet.trade.dto.ProjectInvestorPlanAmountSumDTO;
import com.niiwoo.civet.trade.dto.common.RefundCallBackForAccountDTO;
import com.niiwoo.civet.trade.dto.common.TradeBatchTransOrderDTO;
import com.niiwoo.civet.trade.enums.ProjectPlanStatusEnum;
import com.niiwoo.civet.trade.service.local.kaola.KaoLaLiCaiRepaymentService;
import com.niiwoo.civet.trade.utils.RepaymentUtil;
import com.niiwoo.tripod.tiancheng.component.TianChengRefundEventService;
import com.niiwoo.tripod.tiancheng.component.TianchengDataFlowService;
import com.niiwoo.tripod.tiancheng.request.df.InvestRefundRequest;
import com.niiwoo.tripod.tiancheng.request.df.ProjectOverdueEventRequest;
import com.niiwoo.tripod.tiancheng.request.df.ProjectRefundEventRequest;
import com.niiwoo.tripod.tiancheng.request.df.ProjectRefundEventRequestDetail;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Function;

/**
 * Created by yuanguang on 2018/1/10.
 */
@Service
@Slf4j
public class TianChengLocalService {
    @Autowired
    private ProjectBorrowerPlanMapperExt projectBorrowerPlanMapperExt;
    @Autowired
    private ProjectInvestorPlanMapperExt projectInvestorPlanMapperExt;
    @Autowired
    private TianchengDataFlowService tianchengDataFlowService;
    @Autowired
    private ProjectMapperExt projectMapperExt;
    @Autowired
    private ProjectBorrowerSummaryMapperExt projectBorrowerSummaryMapperExt;
    @Autowired
    private TianChengRefundEventService tianChengRefundEventService;
    @Autowired
    private KaoLaLiCaiRepaymentService kaoLaLiCaiRepaymentService;
    /**
     * 还款成功天秤回流
     * @param dto
     */
    public void sendTianCheng(RefundCallBackForAccountDTO dto) {
        try {
            ProjectRefundEventRequest req=new ProjectRefundEventRequest();
            List<ProjectRefundEventRequestDetail> list=new ArrayList<>();
            List<ProjectBorrowerPlan> projectBorrowerPlans = projectBorrowerPlanMapperExt.queryProjectBorrowerPlanListPeriodAscByProjectIdAndBorrowerUserId(dto.getProjectId(), dto.getBorrowerUserId());
            projectBorrowerPlans.forEach(biz->{
                ProjectRefundEventRequestDetail detail = new ProjectRefundEventRequestDetail();
                detail.setCurrentPeriods(biz.getCurrentPeriod());
                detail.setProjectId(biz.getProjectId());
                detail.setUserId(biz.getBorrowerUserId());
                detail.setTotalPeriods(biz.getTotalPeriod());
                int overDueDay = RepaymentUtil.getOverdueDay(biz.getRefundDate(),new Date());
                if(overDueDay>0){
                    detail.setOverdueDay(overDueDay);
                    detail.setOverdueAmount(biz.getCapital().add(biz.getInterest()).subtract(biz.getRefundedCapital()).subtract(biz.getRefundedInterest()));
                }
                detail.setRealCostAmount(biz.getRefundedCapital());
                detail.setRealRefundInterest(biz.getRefundedInterest());
                detail.setOverdueFine( biz.getPenaltyFee());
                if(biz.getGenerateSource()==1){
                    detail.setStatus(ProjectPlanStatusEnum.BADREFUND.getTianchengStatus());
                }
                else{
                    detail.setStatus(ProjectPlanStatusEnum.enumOf(biz.getRefundStatus()).getTianchengStatus());
                }
                detail.setRealRefundDate(biz.getOverTime()!=null?biz.getOverTime().getTime():new Date().getTime());
                detail.setUpdateTime(biz.getRefundDate().getTime());
                list.add(detail);
            });

            ProjectBorrowerAmountSumDTO amountSumDTO = projectBorrowerPlanMapperExt.sumProjectBorrowerPlanAmountByProjectIdAndBorrowerUserId(dto.getProjectId(), dto.getBorrowerUserId());
            Assert.notNull(amountSumDTO, "数据异常，projectBorrowerAmountSumDTO不可空");
            req.setProjecterPayment(list);
            req.setUserId(dto.getBorrowerUserId());
            req.setProjectId(dto.getProjectId());
            req.setUpdateTime(new Date().getTime());
            req.setBorrowedAmount(amountSumDTO.getBorrowedAmount());
            BigDecimal doneAmount = amountSumDTO.getRefundedCapital().add(amountSumDTO.getRefundedInterest()).add(amountSumDTO.getRefundedManagementFee())
                    .add(amountSumDTO.getRefundedGuaranteeFee()).add(amountSumDTO.getRefundedPenaltyFee());
            req.setDoneAmount(doneAmount);
            BigDecimal totalAmount = amountSumDTO.getBorrowedAmount().add(amountSumDTO.getInterest()).add(amountSumDTO.getManagementFee()).add(amountSumDTO.getGuaranteeFee()).add(amountSumDTO.getPenaltyFee());
            req.setLateAmount(totalAmount.subtract(doneAmount));
            log.info("还款回调天秤回流refundSucceed入参，req={}", JSON.toJSONString(req));
            RpcContext.getContext().asyncCall(new Runnable() {
                @Override
                public void run() {
                    //天秤回流
                    tianChengRefundEventService.refundSucceed(req);
                }
            });
        }catch (Exception e ){
            log.error("sendTianCheng Exception,",e);
        }
    }

    public void handleTianChengInvestRefund(RefundCallBackForAccountDTO dto){
        try {
            List<ProjectInvestorPlanAmountSumDTO> planAmountSumDTOList = projectInvestorPlanMapperExt.sumProjectInvestorPlanAmountByProjectIdAndUserId(dto.getProjectId());
            Assert.notEmpty(planAmountSumDTOList,"数据异常planAmountSumDTOList不可空");
            ProjectInvestorPlanAmountSumDTO planAmount = planAmountSumDTOList.get(0);
            InvestRefundRequest req=new InvestRefundRequest();
            req.setUserId(dto.getBorrowerUserId());
            req.setRealRevenue(planAmount.getReceivedInterest().add(planAmount.getReceivedPenaltyFee()));
            req.setRealBackDate(new Date().getTime());
            req.setRealAmount(planAmount.getReceivedCapital().add(planAmount.getReceivedInterest()).add(planAmount.getReceivedPenaltyFee()));
            req.setInvestOrderId(planAmount.getInvestOrderId().toString());
            req.setBid(dto.getProjectId().toString());
            log.info("还款回调天秤回流investRefund入参，req={}",JSON.toJSONString(req));
            tianchengDataFlowService.investRefund(req);
        }catch (Exception e ){
            log.error("investRefund Exception,",e);
        }
    }


    private void commonHandleTianChengRefund(TradeBatchTransOrderDTO dtoSrc, DateTime refundDate, Function<ProjectBorrowerSummary, BigDecimal> getRepayAmount) {
        RpcContext.getContext().asyncCall(() -> {
            try {
                Project project = projectMapperExt.selectByPrimaryKey(dtoSrc.getProjectId());
                Assert.notNull(project, "数据异常，project不可空");
                ProjectBorrowerSummary summary = projectBorrowerSummaryMapperExt.selectByPrimaryKey(dtoSrc.getProjectId());
                Assert.notNull(summary, "数据异常，summary不可空");
                BigDecimal repayAmount = getRepayAmount.apply(summary);
                ProjectOverdueEventRequest projectOverdueEventRequest = new ProjectOverdueEventRequest();
                projectOverdueEventRequest.setUserId(dtoSrc.getBorrowerUserId());
                projectOverdueEventRequest.setProjectId(dtoSrc.getProjectId());
                projectOverdueEventRequest.setType(project.getSubStatus());
                int days = RepaymentUtil.getOverdueDay(refundDate.toDate(), new Date());
                projectOverdueEventRequest.setDays(days < 0 ? 0 : days);
                projectOverdueEventRequest.setYhAmount(repayAmount);
                BigDecimal refundAmount = summary.getRefundedCorpus().add(summary.getRefundedInterest()).
                        add(summary.getRefundedManagementFee()).add(summary.getRefundedGuaranteeFee()).add(summary.getRefundedPenaltyFee());
                projectOverdueEventRequest.setDoneAmount(refundAmount);
                projectOverdueEventRequest.setUnpaidAmount(repayAmount.subtract(refundAmount));
                log.info("handleTianChengRefund-projectOverdue入参：projectOverdueEventRequest={}",JSON.toJSONString(projectOverdueEventRequest));
                tianChengRefundEventService.projectOverdue(projectOverdueEventRequest);
            }catch (Exception e ){
                log.error("handleTianChengRefund Exception,",e);
            }
        });
    }

    /**
     * 资金端 逾期还款通知天秤
     * @param dtoSrc
     * @param refundDate
     */
    public void handleTianChengRefund4Fund(TradeBatchTransOrderDTO dtoSrc, DateTime refundDate){
        commonHandleTianChengRefund(dtoSrc, refundDate,
                (ProjectBorrowerSummary summary) -> kaoLaLiCaiRepaymentService.getImmediateRepayAmount(summary));
    }
}
